package org.hong.monkey.crawl

import java.util.{HashMap,List,ArrayList}
import org.apache.curator.framework._
import org.apache.curator.retry._
import org.zeromq.ZMQ
import ProcessRouter.MessageStruct.ManagerInfoStruct
import scala.collection.JavaConversions.asScalaBuffer

/**
 * Created by open on 2016/12/15.
 */
object WebkitUtils {

  private val rootPath = "/spider_v2"
  private val sessionTime = 4000
  private var groupMap = new HashMap[String, List[String]]()
  private var zkclient:CuratorFramework = null
  val context = ZMQ.context(10)

  def connect(zkhost:String) = {
    val retryPolicy = new ExponentialBackoffRetry(1000, 3)
    zkclient = CuratorFrameworkFactory.newClient(zkhost, retryPolicy)
    zkclient.start()
  }

  def getNodes(group:String): List[String] = {
    var nodes = zkclient.getChildren().watched().forPath(rootPath + "/" + group)
    if (nodes == null) new ArrayList[String]() else nodes
  }

  def getGroups(): List[String] = {
    var nodes = zkclient.getChildren().watched().forPath(rootPath)
    if (nodes == null) new ArrayList[String]() else nodes
  }

  def getData(path:String): Array[Byte] = {
    zkclient.getData().forPath(path)
  }

  def close() = {
    if (zkclient != null) {
      zkclient.close()
      zkclient = null
    }
  }

  def getProtocolFromGroup(group:String, isStatic:Boolean = false): String = {
    var protocol = ""
    val mpath = rootPath + "/" + group
    var mlist:List[String] = null

    try {
      mlist = getNodes(group)
    } catch {
      case e:Throwable => e.printStackTrace()
        return ""
    }

    var score = -1.0
    var first = true
    var tcurrpc = 0.0
    var toverflowpc = 0.0
    var ntoverflowpc = 0.0

    var infos:List[ManagerInfoStruct] = new ArrayList[ManagerInfoStruct]()

    for (m:String <- mlist) {
      val dpath = mpath + "/" + m + "/stateinfo"
      try {
        if (zkclient.checkExists().forPath(dpath) != null) {
          val data = getData(dpath)
          val is = ManagerInfoStruct.parseFrom(data)
          val cs:Int = if (isStatic) is.getScoresize() else is.getDcoresize()
          if (cs != 0 && is.getMempercent() > 25) {
            val tc = if (isStatic) is.getScurrentpc() else is.getDcurrentpc()
            tcurrpc += tc

            val of = if(isStatic) is.getSoverflowpc() else is.getDoverflowpc()
            if (of > 0) {
              toverflowpc += of
            } else if (of < 0) {
              ntoverflowpc += of
            }

            infos.add(is)
          }
        }
      } catch {
        case e:Throwable => e.printStackTrace()
      }
    }

    ntoverflowpc = -ntoverflowpc
    for (info <- infos) {
      var tcurrpcscore = 0.0
      if (tcurrpc != 0)
        tcurrpcscore = if (isStatic) info.getScurrentpc()/tcurrpc else info.getDcurrentpc()/tcurrpc

      var tsc = 0.2*(info.getMempercent()/100) - 0.6 * tcurrpcscore
      val of = if(isStatic) info.getSoverflowpc() else info.getDoverflowpc()
      if (of > 0)
        tsc -= 0.2*(of/toverflowpc)
      else
        tsc -= 0.2*(of/ntoverflowpc)

      if (first) {
        first = false
        score = tsc
        protocol = info.getProtocol()
      } else if (tsc > score) {
        score = tsc
        protocol =info.getProtocol()
      }
    }
    return protocol
  }

}
